Question 1 In class we computed the run expectancy matrix for the 2016 season. We used this quantity to assess the value of stolen bases and we computed the marginal break even stolen base percentage required to justify an attempt. Do the following:
fields = read_csv("fields.csv")
## Rows: 97 Columns: 3
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): Description, Header
## dbl (1): Field number
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
dat2016 = read_csv("all2016.csv",
col_names = pull(fields, Header),
na = character())
## Warning: One or more parsing issues, call `problems()` on your data frame for details,
## e.g.:
## dat <- vroom(...)
## problems(dat)
## Rows: 190715 Columns: 97
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (35): GAME_ID, AWAY_TEAM_ID, PITCH_SEQ_TX, BAT_ID, BAT_HAND_CD, RESP_BAT...
## dbl (35): INN_CT, BAT_HOME_ID, OUTS_CT, BALLS_CT, STRIKES_CT, AWAY_SCORE_CT,...
## lgl (27): LEADOFF_FL, PH_FL, BAT_EVENT_FL, AB_FL, SH_FL, SF_FL, DP_FL, TP_FL...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
dat2016_updated = dat2016 %>%
mutate(RUNS = AWAY_SCORE_CT + HOME_SCORE_CT,
HALF.INNING = paste(GAME_ID, INN_CT, BAT_HOME_ID),
RUNS.SCORED = (BAT_DEST_ID > 3) + (RUN1_DEST_ID > 3) +
(RUN2_DEST_ID > 3) + (RUN3_DEST_ID > 3))
half_innings = dat2016_updated %>%
group_by(HALF.INNING) %>%
summarise(Outs.Inning = sum(EVENT_OUTS_CT),
Runs.Inning = sum(RUNS.SCORED),
Runs.Start = first(RUNS),
MAX.RUNS = Runs.Inning + Runs.Start)
dat2016_updated = dat2016_updated %>%
inner_join(half_innings, by = "HALF.INNING") %>%
mutate(RUNS.ROI = MAX.RUNS - RUNS)
dat2016_updated =
dat2016_updated %>% mutate(BASES = paste(ifelse(BASE1_RUN_ID != "",1,0),
ifelse(BASE2_RUN_ID != "",1,0),
ifelse(BASE3_RUN_ID != "",1,0), sep = ""),
STATE = paste(BASES, OUTS_CT))
dat2016_updated = dat2016_updated %>%
mutate(NRUNNER1 = as.numeric(RUN1_DEST_ID == 1 | BAT_DEST_ID == 1),
NRUNNER2 = as.numeric(RUN1_DEST_ID == 2 | RUN2_DEST_ID == 2 | BAT_DEST_ID == 2),
NRUNNER3 = as.numeric(RUN1_DEST_ID == 3 | RUN2_DEST_ID == 3 |
RUN3_DEST_ID == 3 | BAT_DEST_ID == 3),
NOUTS = OUTS_CT + EVENT_OUTS_CT,
NEW.BASES = paste(NRUNNER1, NRUNNER2, NRUNNER3, sep = ""),
NEW.STATE = paste(NEW.BASES, NOUTS)) %>%
filter((STATE != NEW.STATE) | (RUNS.SCORED > 0)) %>%
filter(Outs.Inning == 3)
RUNS = dat2016_updated %>%
group_by(STATE) %>%
summarize(Mean = mean(RUNS.ROI)) %>%
mutate(Outs = substr(STATE, 5, 5)) %>%
arrange(Outs)
RUNS_out_2016 = matrix(round(RUNS$Mean, 2), 8, 3)
dimnames(RUNS_out_2016)[[1]] = c("000","001","010","011",
"100","101","110","111")
dimnames(RUNS_out_2016)[[2]] = c("0 outs", "1 out", "2 outs")
RUNS_out_2016
## 0 outs 1 out 2 outs
## 000 0.50 0.27 0.11
## 001 1.35 0.94 0.37
## 010 1.13 0.67 0.31
## 011 1.93 1.36 0.55
## 100 0.86 0.51 0.22
## 101 1.72 1.20 0.48
## 110 1.44 0.92 0.41
## 111 2.11 1.54 0.70
dat2016_SB = dat2016_updated%>%
select(POS2_FLD_ID, EVENT_TX)%>%
filter(grepl("SB", EVENT_TX))%>%
group_by(POS2_FLD_ID) %>%
summarise(total_SB = n())
dat2016_CB <- dat2016_updated %>%
select(POS2_FLD_ID, RUN1_CS_FL, RUN2_CS_FL, RUN3_CS_FL, EVENT_TX) %>%
mutate(total_CS_pg = RUN1_CS_FL + RUN2_CS_FL + RUN3_CS_FL) %>%
select(POS2_FLD_ID, total_CS_pg, EVENT_TX)%>%
group_by(POS2_FLD_ID) %>%
summarise(total_CS = sum(total_CS_pg))
dat2016_steal <- merge(x = dat2016_CB, y = dat2016_SB, by = "POS2_FLD_ID")
dat2016_BC = dat2016_steal%>%
mutate(total_attempts = total_SB + total_CS)%>%
filter(total_attempts >= 10)%>%
mutate(caught_PCT = total_CS/total_attempts)%>%
arrange(desc(caught_PCT))
dat2016_BC
top10_catchers = head(dat2016_BC, 10)
top10_catchers
worst10_catchers = tail(dat2016_BC, 10)
worst10_catchers
dat2016_steal <- dat2016_updated %>%
left_join(RUNS, by = "STATE") %>%
rename(run_value = Mean)
dat2016_steal <- dat2016_steal %>%
mutate(
SB_value = ifelse(EVENT_CD == 4, run_value, 0),
CS_value = ifelse(EVENT_CD == 6, run_value, 0)
)
dat2016_steal <- dat2016_steal %>%
group_by(STATE) %>%
summarise(
total_SB = sum(SB_value),
total_CS = sum(CS_value),
total_attempts = total_SB + total_CS,
avg_run_value_SB = mean(SB_value),
avg_run_value_CS = mean(CS_value)
) %>%
filter(total_attempts >= 10) %>%
mutate(
break_even_pct = avg_run_value_CS / (avg_run_value_SB - avg_run_value_CS)
)
dat2016_steal
min(dat2016_steal$break_even_pct)
## [1] 0.1265823
#it is best to attempt a SB when there is a runner on first and third with 1 out
Question 2 In the Simulation Notes we considered team specific transition probabilities for one base out state corresponding to the St. Louis Cardinals in 2016. Do the following:
cardinals_2016 = dat2016 %>%
filter(AWAY_TEAM_ID == "SLN" | grepl("SLN", GAME_ID))%>%
mutate(RUNS = AWAY_SCORE_CT + HOME_SCORE_CT,
HALF.INNING = paste(GAME_ID, INN_CT, BAT_HOME_ID),
RUNS.SCORED = (BAT_DEST_ID > 3) + (RUN1_DEST_ID > 3) +
(RUN2_DEST_ID > 3) + (RUN3_DEST_ID > 3))
half_innings_SLN = cardinals_2016 %>%
group_by(HALF.INNING) %>%
summarize(Outs.Inning = sum(EVENT_OUTS_CT),
Runs.Inning = sum(RUNS.SCORED),
Runs.Start = first(RUNS),
MAX.RUNS = Runs.Inning + Runs.Start)
cardinals_2016 = cardinals_2016 %>%
inner_join(half_innings_SLN, by = "HALF.INNING")%>%
mutate(RUNS.ROI = MAX.RUNS - RUNS)%>%
mutate(BASES = paste(ifelse(BASE1_RUN_ID > '', 1, 0),
ifelse(BASE2_RUN_ID > '', 1, 0),
ifelse(BASE3_RUN_ID > '', 1, 0), sep = ""),
STATE = paste(BASES, OUTS_CT),
NRUNNER1 = as.numeric(RUN1_DEST_ID == 1 | BAT_DEST_ID == 1),
NRUNNER2 = as.numeric(RUN1_DEST_ID == 2 | RUN2_DEST_ID == 2 | BAT_DEST_ID == 2),
NRUNNER3 = as.numeric(RUN1_DEST_ID == 3 | RUN2_DEST_ID == 3 |
RUN3_DEST_ID == 3 | BAT_DEST_ID == 3),
NOUTS = OUTS_CT + EVENT_OUTS_CT,
NEW.BASES = paste(NRUNNER1, NRUNNER2, NRUNNER3, sep = ""),
NEW.STATE = paste(NEW.BASES, NOUTS))
cardinals_2016 = cardinals_2016 %>%
filter((STATE != NEW.STATE) | (RUNS.SCORED > 0))
cardinals_2016C = cardinals_2016 %>%
filter(Outs.Inning == 3, BAT_EVENT_FL == TRUE)
cardinals_2016C = cardinals_2016C %>%
mutate(NEW.STATE = gsub("[0-1]{3} 3", "3", NEW.STATE))
T_matrix_2016 = cardinals_2016C %>%
select(STATE, NEW.STATE) %>%
table()
T_matrix_2016
## NEW.STATE
## STATE 000 0 000 1 000 2 001 0 001 1 001 2 010 0 010 1 010 2 011 0 011 1 011 2
## 000 0 109 1999 0 19 0 0 184 0 0 0 0 0
## 000 1 0 62 1456 0 12 0 0 96 0 0 0 0
## 000 2 0 0 59 0 0 3 0 0 60 0 0 0
## 001 0 0 5 0 0 14 0 2 1 0 0 0 0
## 001 1 0 2 28 0 0 42 0 9 2 0 0 0
## 001 2 0 0 6 0 0 1 0 0 8 0 0 0
## 010 0 10 1 2 1 60 0 16 95 0 1 0 0
## 010 1 0 9 0 0 2 74 0 15 142 0 1 0
## 010 2 0 0 12 0 0 1 0 0 24 0 0 0
## 011 0 1 0 0 0 7 0 0 4 0 0 11 0
## 011 1 0 4 0 0 0 11 0 5 11 0 0 21
## 011 2 0 0 4 0 0 0 0 0 6 0 0 0
## 100 0 14 2 88 4 1 0 14 69 0 17 0 0
## 100 1 0 20 1 0 8 3 0 10 55 0 31 0
## 100 2 0 0 20 0 0 5 0 0 11 0 0 27
## 101 0 3 0 11 1 0 0 0 3 0 1 1 0
## 101 1 0 9 0 0 2 0 0 1 7 0 7 5
## 101 2 0 0 5 0 0 0 0 0 7 0 0 3
## 110 0 7 0 0 0 0 16 3 1 2 5 22 0
## 110 1 0 5 1 0 2 0 0 6 1 0 12 19
## 110 2 0 0 11 0 0 1 0 0 10 0 0 8
## 111 0 1 0 0 0 0 1 0 0 0 2 3 1
## 111 1 0 4 0 0 1 0 0 0 0 0 4 9
## 111 2 0 0 3 0 0 0 0 0 0 0 0 9
## NEW.STATE
## STATE 100 0 100 1 100 2 101 0 101 1 101 2 110 0 110 1 110 2 111 0 111 1 111 2
## 000 0 720 0 0 0 0 0 0 0 0 0 0 0
## 000 1 0 508 0 0 0 0 0 0 0 0 0 0
## 000 2 0 0 398 0 0 0 0 0 0 0 0 0
## 001 0 6 1 0 6 0 0 0 0 0 0 0 0
## 001 1 0 21 2 0 21 0 0 0 0 0 0 0
## 001 2 0 0 25 0 0 30 0 0 0 0 0 0
## 010 0 13 4 0 21 0 0 20 0 0 0 0 0
## 010 1 0 21 5 0 27 0 0 41 0 0 0 0
## 010 2 0 0 30 0 0 21 0 0 67 0 0 0
## 011 0 2 0 0 3 0 0 1 0 0 3 0 0
## 011 1 0 5 0 0 13 3 0 2 2 0 24 0
## 011 2 0 0 12 0 0 3 0 0 0 0 0 34
## 100 0 0 329 0 29 0 0 130 0 0 0 0 0
## 100 1 0 0 405 0 40 0 0 153 0 0 0 0
## 100 2 0 0 2 0 0 43 0 0 159 0 0 0
## 101 0 0 9 0 2 16 0 7 1 0 6 0 0
## 101 1 0 0 24 0 8 37 0 15 3 0 15 0
## 101 2 0 0 0 0 0 11 0 0 17 0 0 16
## 110 0 0 0 1 2 17 0 6 53 0 25 0 0
## 110 1 0 0 1 0 8 27 0 14 102 0 41 0
## 110 2 0 0 1 0 0 11 0 0 15 0 0 41
## 111 0 0 0 0 2 4 0 4 3 0 8 13 0
## 111 1 0 0 1 0 2 13 0 4 9 0 20 26
## 111 2 0 0 0 0 0 6 0 0 6 0 0 12
## NEW.STATE
## STATE 3
## 000 0 0
## 000 1 0
## 000 2 1215
## 001 0 0
## 001 1 2
## 001 2 104
## 010 0 0
## 010 1 0
## 010 2 253
## 011 0 0
## 011 1 2
## 011 2 77
## 100 0 0
## 100 1 110
## 100 2 552
## 101 0 0
## 101 1 16
## 101 2 122
## 110 0 0
## 110 1 35
## 110 2 266
## 111 0 0
## 111 1 18
## 111 2 93
P_matrix_2016 = prop.table(T_matrix_2016, 1)
P_matrix_2016 = rbind(P_matrix_2016, c(rep(0, 24), 1))
round(P_matrix_2016,2)
## 000 0 000 1 000 2 001 0 001 1 001 2 010 0 010 1 010 2 011 0 011 1 011 2
## 000 0 0.04 0.66 0.00 0.01 0.00 0.00 0.06 0.00 0.00 0.00 0.00 0.00
## 000 1 0.00 0.03 0.68 0.00 0.01 0.00 0.00 0.04 0.00 0.00 0.00 0.00
## 000 2 0.00 0.00 0.03 0.00 0.00 0.00 0.00 0.00 0.03 0.00 0.00 0.00
## 001 0 0.00 0.14 0.00 0.00 0.40 0.00 0.06 0.03 0.00 0.00 0.00 0.00
## 001 1 0.00 0.02 0.22 0.00 0.00 0.33 0.00 0.07 0.02 0.00 0.00 0.00
## 001 2 0.00 0.00 0.03 0.00 0.00 0.01 0.00 0.00 0.05 0.00 0.00 0.00
## 010 0 0.04 0.00 0.01 0.00 0.25 0.00 0.07 0.39 0.00 0.00 0.00 0.00
## 010 1 0.00 0.03 0.00 0.00 0.01 0.22 0.00 0.04 0.42 0.00 0.00 0.00
## 010 2 0.00 0.00 0.03 0.00 0.00 0.00 0.00 0.00 0.06 0.00 0.00 0.00
## 011 0 0.03 0.00 0.00 0.00 0.22 0.00 0.00 0.12 0.00 0.00 0.34 0.00
## 011 1 0.00 0.04 0.00 0.00 0.00 0.11 0.00 0.05 0.11 0.00 0.00 0.20
## 011 2 0.00 0.00 0.03 0.00 0.00 0.00 0.00 0.00 0.04 0.00 0.00 0.00
## 100 0 0.02 0.00 0.13 0.01 0.00 0.00 0.02 0.10 0.00 0.02 0.00 0.00
## 100 1 0.00 0.02 0.00 0.00 0.01 0.00 0.00 0.01 0.07 0.00 0.04 0.00
## 100 2 0.00 0.00 0.02 0.00 0.00 0.01 0.00 0.00 0.01 0.00 0.00 0.03
## 101 0 0.05 0.00 0.18 0.02 0.00 0.00 0.00 0.05 0.00 0.02 0.02 0.00
## 101 1 0.00 0.06 0.00 0.00 0.01 0.00 0.00 0.01 0.05 0.00 0.05 0.03
## 101 2 0.00 0.00 0.03 0.00 0.00 0.00 0.00 0.00 0.04 0.00 0.00 0.02
## 110 0 0.04 0.00 0.00 0.00 0.00 0.10 0.02 0.01 0.01 0.03 0.14 0.00
## 110 1 0.00 0.02 0.00 0.00 0.01 0.00 0.00 0.02 0.00 0.00 0.04 0.07
## 110 2 0.00 0.00 0.03 0.00 0.00 0.00 0.00 0.00 0.03 0.00 0.00 0.02
## 111 0 0.02 0.00 0.00 0.00 0.00 0.02 0.00 0.00 0.00 0.05 0.07 0.02
## 111 1 0.00 0.04 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.00 0.04 0.08
## 111 2 0.00 0.00 0.02 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.07
## 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
## 100 0 100 1 100 2 101 0 101 1 101 2 110 0 110 1 110 2 111 0 111 1 111 2
## 000 0 0.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
## 000 1 0.00 0.24 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
## 000 2 0.00 0.00 0.23 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
## 001 0 0.17 0.03 0.00 0.17 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
## 001 1 0.00 0.16 0.02 0.00 0.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00
## 001 2 0.00 0.00 0.14 0.00 0.00 0.17 0.00 0.00 0.00 0.00 0.00 0.00
## 010 0 0.05 0.02 0.00 0.09 0.00 0.00 0.08 0.00 0.00 0.00 0.00 0.00
## 010 1 0.00 0.06 0.01 0.00 0.08 0.00 0.00 0.12 0.00 0.00 0.00 0.00
## 010 2 0.00 0.00 0.07 0.00 0.00 0.05 0.00 0.00 0.16 0.00 0.00 0.00
## 011 0 0.06 0.00 0.00 0.09 0.00 0.00 0.03 0.00 0.00 0.09 0.00 0.00
## 011 1 0.00 0.05 0.00 0.00 0.13 0.03 0.00 0.02 0.02 0.00 0.23 0.00
## 011 2 0.00 0.00 0.09 0.00 0.00 0.02 0.00 0.00 0.00 0.00 0.00 0.25
## 100 0 0.00 0.47 0.00 0.04 0.00 0.00 0.19 0.00 0.00 0.00 0.00 0.00
## 100 1 0.00 0.00 0.48 0.00 0.05 0.00 0.00 0.18 0.00 0.00 0.00 0.00
## 100 2 0.00 0.00 0.00 0.00 0.00 0.05 0.00 0.00 0.19 0.00 0.00 0.00
## 101 0 0.00 0.15 0.00 0.03 0.26 0.00 0.11 0.02 0.00 0.10 0.00 0.00
## 101 1 0.00 0.00 0.16 0.00 0.05 0.25 0.00 0.10 0.02 0.00 0.10 0.00
## 101 2 0.00 0.00 0.00 0.00 0.00 0.06 0.00 0.00 0.09 0.00 0.00 0.09
## 110 0 0.00 0.00 0.01 0.01 0.11 0.00 0.04 0.33 0.00 0.16 0.00 0.00
## 110 1 0.00 0.00 0.00 0.00 0.03 0.10 0.00 0.05 0.37 0.00 0.15 0.00
## 110 2 0.00 0.00 0.00 0.00 0.00 0.03 0.00 0.00 0.04 0.00 0.00 0.11
## 111 0 0.00 0.00 0.00 0.05 0.10 0.00 0.10 0.07 0.00 0.19 0.31 0.00
## 111 1 0.00 0.00 0.01 0.00 0.02 0.12 0.00 0.04 0.08 0.00 0.18 0.23
## 111 2 0.00 0.00 0.00 0.00 0.00 0.05 0.00 0.00 0.05 0.00 0.00 0.09
## 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
## 3
## 000 0 0.00
## 000 1 0.00
## 000 2 0.70
## 001 0 0.00
## 001 1 0.02
## 001 2 0.60
## 010 0 0.00
## 010 1 0.00
## 010 2 0.62
## 011 0 0.00
## 011 1 0.02
## 011 2 0.57
## 100 0 0.00
## 100 1 0.13
## 100 2 0.67
## 101 0 0.00
## 101 1 0.11
## 101 2 0.67
## 110 0 0.00
## 110 1 0.13
## 110 2 0.73
## 111 0 0.00
## 111 1 0.16
## 111 2 0.72
## 1.00
#creating the transition probability matrix
cardinals_2016C = cardinals_2016C %>%
mutate(HOME_TEAM_ID = str_sub(GAME_ID, 1, 3),
BATTING.TEAM = ifelse(BAT_HOME_ID == 0,
AWAY_TEAM_ID, HOME_TEAM_ID))
Team.T.S = cardinals_2016C %>%
group_by(BATTING.TEAM, STATE, NEW.STATE) %>%
tally()
SLN.Trans = Team.T.S %>% filter(BATTING.TEAM == "SLN") %>%
mutate(p = n / sum(n))
All.Trans = cardinals_2016C %>%
group_by(NEW.STATE) %>%
tally() %>%
mutate(p = n / sum(n))
SLN.Trans %>% inner_join(All.Trans, by = "NEW.STATE") %>%
mutate(p.EST = n.x / (1274 + n.x) * p.x + 1274 / (1274 + n.x) * p.y) %>%
mutate(p.EST = p.EST / sum(p.EST)) %>%
select(BATTING.TEAM, NEW.STATE, p.x, p.y, p.EST)
## Adding missing grouping variables: `STATE`
SLN.Trans
#normalized outcomes for al base states
P_matrix_3_2016 = P_matrix_2016 %*% P_matrix_2016 %*% P_matrix_2016
P_matrix_3_2016 %>% as_tibble(rownames = "STATE") %>%
filter(STATE == "000 0") %>%
gather(key = "NEW.STATE", value = "Prob", -STATE)
#movement through the base out states after 3 PAs to start a half inning for SLN
dat2016 = dat2016 %>%
mutate(RUNS = AWAY_SCORE_CT + HOME_SCORE_CT,
HALF.INNING = paste(GAME_ID, INN_CT, BAT_HOME_ID),
RUNS.SCORED = (BAT_DEST_ID > 3) + (RUN1_DEST_ID > 3) +
(RUN2_DEST_ID > 3) + (RUN3_DEST_ID > 3))
half_innings = dat2016 %>%
group_by(HALF.INNING) %>%
summarize(Outs.Inning = sum(EVENT_OUTS_CT),
Runs.Inning = sum(RUNS.SCORED),
Runs.Start = first(RUNS),
MAX.RUNS = Runs.Inning + Runs.Start)
dat2016 = dat2016 %>%
inner_join(half_innings, by = "HALF.INNING") %>%
mutate(BASES = paste(ifelse(BASE1_RUN_ID > '', 1, 0),
ifelse(BASE2_RUN_ID > '', 1, 0),
ifelse(BASE3_RUN_ID > '', 1, 0), sep = ""),
STATE = paste(BASES, OUTS_CT),
NRUNNER1 = as.numeric(RUN1_DEST_ID == 1 | BAT_DEST_ID == 1),
NRUNNER2 = as.numeric(RUN1_DEST_ID == 2 | RUN2_DEST_ID == 2 | BAT_DEST_ID == 2),
NRUNNER3 = as.numeric(RUN1_DEST_ID == 3 | RUN2_DEST_ID == 3 |
RUN3_DEST_ID == 3 | BAT_DEST_ID == 3),
NOUTS = OUTS_CT + EVENT_OUTS_CT,
NEW.BASES = paste(NRUNNER1, NRUNNER2, NRUNNER3, sep = ""),
NEW.STATE = paste(NEW.BASES, NOUTS))
dat2016 = dat2016 %>% filter((STATE != NEW.STATE) | (RUNS.SCORED > 0))
dat2016C = dat2016 %>% filter(Outs.Inning == 3, BAT_EVENT_FL == TRUE)
dat2016C = dat2016C %>% mutate(NEW.STATE = gsub("[0-1]{3} 3", "3", NEW.STATE))
T_matrix = dat2016C %>%
select(STATE, NEW.STATE) %>%
table()
P_matrix = prop.table(T_matrix, 1)
P_matrix = rbind(P_matrix, c(rep(0, 24), 1))
P_matrix_3 = P_matrix %*% P_matrix %*% P_matrix
P_matrix_3 %>% as_tibble(rownames = "STATE") %>%
filter(STATE == "000 0") %>%
gather(key = "NEW.STATE", value = "Prob", -STATE)
difference_matrix <- P_matrix_3 - P_matrix_3_2016
difference_matrix
## 000 0 000 1 000 2 001 0 001 1
## 000 0 -6.490883e-04 0.0028539445 -3.558890e-03 0.0001586831 -1.311976e-03
## 000 1 0.000000e+00 0.0002003984 1.539482e-03 0.0000000000 -2.624754e-05
## 000 2 0.000000e+00 0.0000000000 -7.965831e-05 0.0000000000 0.000000e+00
## 001 0 -1.242886e-03 -0.0038779531 1.392255e-02 0.0001847218 -1.767864e-03
## 001 1 0.000000e+00 -0.0003239156 -2.569653e-03 0.0000000000 -7.705327e-05
## 001 2 0.000000e+00 0.0000000000 -7.124370e-04 0.0000000000 0.000000e+00
## 010 0 -2.087094e-04 -0.0019641133 -7.208625e-03 0.0001802314 -7.941749e-04
## 010 1 0.000000e+00 -0.0003742649 -1.407249e-03 0.0000000000 -5.502009e-05
## 010 2 0.000000e+00 0.0000000000 -3.828949e-04 0.0000000000 0.000000e+00
## 011 0 1.941019e-05 -0.0032607541 1.318753e-03 0.0003207199 -4.728886e-04
## 011 1 0.000000e+00 -0.0015756483 -6.924897e-03 0.0000000000 -2.837590e-04
## 011 2 0.000000e+00 0.0000000000 -9.380237e-04 0.0000000000 0.000000e+00
## 100 0 2.593476e-04 -0.0002414708 5.930455e-03 0.0002457131 6.530559e-04
## 100 1 0.000000e+00 -0.0006118447 -1.683291e-04 0.0000000000 -6.954366e-05
## 100 2 0.000000e+00 0.0000000000 -1.496407e-04 0.0000000000 0.000000e+00
## 101 0 -2.215476e-04 -0.0004161962 -1.062944e-02 0.0001921894 2.987031e-04
## 101 1 0.000000e+00 -0.0012211192 -3.218665e-03 0.0000000000 -2.404122e-04
## 101 2 0.000000e+00 0.0000000000 -2.634892e-04 0.0000000000 0.000000e+00
## 110 0 -4.872115e-04 -0.0023217929 -6.677461e-03 0.0001535850 5.308873e-06
## 110 1 0.000000e+00 -0.0007797843 -1.451056e-03 0.0000000000 -1.115419e-04
## 110 2 0.000000e+00 0.0000000000 7.249764e-05 0.0000000000 0.000000e+00
## 111 0 -1.606827e-03 -0.0065666678 -2.290580e-03 0.0001064977 -9.199476e-04
## 111 1 0.000000e+00 -0.0007346100 -1.830191e-03 0.0000000000 -1.074248e-04
## 111 2 0.000000e+00 0.0000000000 -1.666394e-04 0.0000000000 0.000000e+00
## 0.000000e+00 0.0000000000 0.000000e+00 0.0000000000 0.000000e+00
## 001 2 010 0 010 1 010 2 011 0
## 000 0 -0.0020138430 -3.449968e-04 -1.599267e-03 6.104631e-03 0.0006899824
## 000 1 0.0001695892 0.000000e+00 -3.334018e-04 3.472838e-03 0.0000000000
## 000 2 0.0003185696 0.000000e+00 0.000000e+00 -1.179499e-04 0.0000000000
## 001 0 -0.0025981721 -4.269363e-04 1.149631e-03 8.576322e-05 -0.0000402902
## 001 1 0.0005579519 0.000000e+00 -5.140223e-04 4.950051e-05 0.0000000000
## 001 2 0.0004012017 0.000000e+00 0.000000e+00 -6.737570e-04 0.0000000000
## 010 0 -0.0002707163 -5.217322e-05 -1.913926e-03 -4.820386e-04 0.0003219908
## 010 1 0.0007205461 0.000000e+00 -8.565747e-05 -1.472296e-03 0.0000000000
## 010 2 0.0004383014 0.000000e+00 0.000000e+00 -6.159874e-05 0.0000000000
## 011 0 0.0067769582 6.431112e-04 3.550172e-03 1.990219e-04 0.0001119701
## 011 1 0.0012957794 0.000000e+00 -5.344316e-04 1.669659e-04 0.0000000000
## 011 2 0.0004334183 0.000000e+00 0.000000e+00 -6.534955e-04 0.0000000000
## 100 0 0.0024909770 5.872191e-04 -1.084279e-03 1.537984e-03 0.0001013319
## 100 1 0.0009043810 0.000000e+00 2.559653e-04 -1.510680e-03 0.0000000000
## 100 2 0.0004691194 0.000000e+00 0.000000e+00 4.457830e-04 0.0000000000
## 101 0 0.0060632057 5.354874e-04 -1.008626e-03 5.092390e-03 -0.0003929411
## 101 1 0.0010178500 0.000000e+00 -1.071778e-06 -1.821118e-03 0.0000000000
## 101 2 0.0004481059 0.000000e+00 0.000000e+00 1.696753e-04 0.0000000000
## 110 0 0.0009257600 5.261766e-04 -3.172333e-04 -3.787805e-03 -0.0005532662
## 110 1 0.0021193742 0.000000e+00 3.247403e-04 1.756478e-03 0.0000000000
## 110 2 0.0004352357 0.000000e+00 0.000000e+00 4.730328e-04 0.0000000000
## 111 0 0.0010478472 2.814284e-04 -8.678322e-04 -2.928835e-04 -0.0017210202
## 111 1 0.0021522118 0.000000e+00 3.298029e-04 2.016535e-03 0.0000000000
## 111 2 0.0004248213 0.000000e+00 0.000000e+00 4.959913e-04 0.0000000000
## 0.0000000000 0.000000e+00 0.000000e+00 0.000000e+00 0.0000000000
## 011 1 011 2 100 0 100 1 100 2
## 000 0 -0.0006851731 0.0000000000 1.464346e-04 -0.0016947125 -2.051214e-03
## 000 1 -0.0006053198 -0.0021847932 0.000000e+00 0.0002700964 -4.115444e-04
## 000 2 0.0000000000 0.0002190896 0.000000e+00 0.0000000000 1.038605e-04
## 001 0 -0.0049174571 -0.0019118819 -1.307736e-03 0.0081764067 3.152791e-03
## 001 1 -0.0007791153 -0.0015476035 0.000000e+00 -0.0008853755 -1.373896e-03
## 001 2 0.0000000000 -0.0006957471 0.000000e+00 0.0000000000 -7.428729e-04
## 010 0 -0.0007490181 0.0026948397 -6.911117e-04 -0.0023152338 -3.276028e-03
## 010 1 -0.0004471178 -0.0009749485 0.000000e+00 -0.0001769207 -1.454425e-03
## 010 2 0.0000000000 -0.0009121272 0.000000e+00 0.0000000000 -5.213330e-04
## 011 0 -0.0043236662 -0.0025014338 3.619349e-05 0.0058581291 -2.076580e-02
## 011 1 -0.0013443764 -0.0073251746 0.000000e+00 -0.0020791185 -5.224700e-03
## 011 2 0.0000000000 -0.0012291923 0.000000e+00 0.0000000000 -1.432486e-03
## 100 0 -0.0014650328 0.0037273306 -3.064449e-04 0.0045374922 -2.354861e-03
## 100 1 -0.0003089357 0.0002292013 0.000000e+00 0.0001438972 -1.790505e-04
## 100 2 0.0000000000 -0.0013773365 0.000000e+00 0.0000000000 -2.537211e-04
## 101 0 -0.0019829025 0.0041797693 -1.198131e-04 -0.0035211422 2.915029e-03
## 101 1 -0.0008817698 -0.0026167256 0.000000e+00 -0.0007642824 -9.067362e-03
## 101 2 0.0000000000 -0.0010928036 0.000000e+00 0.0000000000 -4.434904e-04
## 110 0 -0.0033293714 0.0001321219 -4.660643e-05 -0.0030267308 -1.318469e-04
## 110 1 -0.0004571530 -0.0038694770 0.000000e+00 -0.0002975768 2.501736e-04
## 110 2 0.0000000000 -0.0007134870 0.000000e+00 0.0000000000 -2.963919e-05
## 111 0 -0.0086558794 -0.0070885080 -1.227660e-03 -0.0010169386 -5.811620e-03
## 111 1 -0.0004105098 -0.0039916800 0.000000e+00 -0.0003807890 -2.685046e-03
## 111 2 0.0000000000 -0.0015233779 0.000000e+00 0.0000000000 -1.865870e-04
## 0.0000000000 0.0000000000 0.000000e+00 0.0000000000 0.000000e+00
## 101 0 101 1 101 2 110 0 110 1
## 000 0 3.120129e-04 -0.0036747452 0.000000e+00 -5.973335e-05 0.0060535892
## 000 1 0.000000e+00 -0.0008907086 -3.813562e-03 0.000000e+00 0.0006373672
## 000 2 0.000000e+00 0.0000000000 5.427031e-04 0.000000e+00 0.0000000000
## 001 0 -1.931546e-04 -0.0074859964 -5.850233e-03 -1.757176e-04 0.0023869147
## 001 1 0.000000e+00 -0.0013103804 -6.357459e-03 0.000000e+00 0.0008830902
## 001 2 0.000000e+00 0.0000000000 -3.474405e-04 0.000000e+00 0.0000000000
## 010 0 8.955785e-05 -0.0029841589 -6.644630e-03 -1.092407e-03 0.0082479119
## 010 1 0.000000e+00 -0.0009738350 -3.176836e-03 0.000000e+00 0.0010760664
## 010 2 0.000000e+00 0.0000000000 -9.527772e-05 0.000000e+00 0.0000000000
## 011 0 4.330042e-04 -0.0010885192 -1.246733e-02 1.135006e-04 0.0025007576
## 011 1 0.000000e+00 -0.0019200064 -6.192020e-03 0.000000e+00 0.0001240776
## 011 2 0.000000e+00 0.0000000000 -4.800651e-04 0.000000e+00 0.0000000000
## 100 0 3.456629e-04 -0.0022229127 -6.513656e-03 -5.389467e-04 0.0029940183
## 100 1 0.000000e+00 -0.0007151325 2.059557e-04 0.000000e+00 0.0012143710
## 100 2 0.000000e+00 0.0000000000 -5.942301e-05 0.000000e+00 0.0000000000
## 101 0 -3.654259e-04 -0.0007395958 -1.276577e-03 -2.532428e-03 0.0048204336
## 101 1 0.000000e+00 -0.0013291282 -1.812253e-03 0.000000e+00 -0.0004433139
## 101 2 0.000000e+00 0.0000000000 3.579703e-05 0.000000e+00 0.0000000000
## 110 0 -4.953929e-04 -0.0039081365 -1.124816e-03 -2.497909e-03 0.0018606519
## 110 1 0.000000e+00 -0.0004182478 -1.616466e-03 0.000000e+00 0.0014375262
## 110 2 0.000000e+00 0.0000000000 4.894518e-04 0.000000e+00 0.0000000000
## 111 0 -1.819543e-03 -0.0098615239 -6.682579e-03 -4.611808e-03 -0.0040988436
## 111 1 0.000000e+00 -0.0004066406 4.711606e-04 0.000000e+00 0.0011198672
## 111 2 0.000000e+00 0.0000000000 -5.960220e-05 0.000000e+00 0.0000000000
## 0.000000e+00 0.0000000000 0.000000e+00 0.000000e+00 0.0000000000
## 110 2 111 0 111 1 111 2 3
## 000 0 0.000000e+00 1.390524e-03 0.0000000000 0.000000e+00 -6.616346e-05
## 000 1 2.067284e-03 0.000000e+00 0.0004043759 0.000000e+00 -4.958547e-04
## 000 2 7.089894e-04 0.000000e+00 0.0000000000 -3.504522e-04 -1.345152e-03
## 001 0 -7.496510e-03 -2.348397e-03 -0.0075933156 0.000000e+00 2.017572e-02
## 001 1 1.310670e-03 0.000000e+00 -0.0006238652 -7.613575e-04 1.432248e-02
## 001 2 -1.530387e-03 0.000000e+00 0.0000000000 -1.198623e-03 5.500064e-03
## 010 0 3.179466e-03 1.703918e-03 0.0027003490 0.000000e+00 1.152880e-02
## 010 1 -2.123698e-03 0.000000e+00 -0.0009983208 1.924167e-03 9.999810e-03
## 010 2 -4.940757e-04 0.000000e+00 0.0000000000 -3.050872e-04 2.334093e-03
## 011 0 -6.796746e-03 3.147004e-06 -0.0041842786 1.996316e-02 1.401340e-02
## 011 1 -2.467419e-03 0.000000e+00 -0.0054699094 -3.939340e-03 4.369398e-02
## 011 2 -3.944070e-04 0.000000e+00 0.0000000000 -4.714773e-03 9.409024e-03
## 100 0 -6.338073e-04 1.263922e-03 0.0054519918 0.000000e+00 -1.476509e-02
## 100 1 8.618178e-04 0.000000e+00 -0.0014036189 2.577638e-03 -1.426093e-03
## 100 2 -4.140273e-05 0.000000e+00 0.0000000000 3.558052e-04 6.108164e-04
## 101 0 7.403726e-03 -4.834188e-04 0.0046838672 5.344293e-03 -1.783904e-02
## 101 1 -5.653038e-04 0.000000e+00 -0.0027393592 2.518012e-03 2.318602e-02
## 101 2 -1.002382e-04 0.000000e+00 0.0000000000 -6.266012e-04 1.873044e-03
## 110 0 -1.402781e-04 -1.825230e-03 -0.0025531902 1.402105e-02 1.559963e-02
## 110 1 2.169879e-04 0.000000e+00 -0.0021856132 4.135183e-03 9.464523e-04
## 110 2 8.166680e-04 0.000000e+00 0.0000000000 -4.619966e-05 -1.497560e-03
## 111 0 -9.695221e-05 -7.309703e-03 -0.0179126056 1.216247e-02 7.686168e-02
## 111 1 2.732448e-03 0.000000e+00 -0.0019544966 1.170702e-03 2.508661e-03
## 111 2 -7.675090e-06 0.000000e+00 0.0000000000 -5.851193e-04 1.608188e-03
## 0.000000e+00 0.000000e+00 0.0000000000 0.000000e+00 0.000000e+00
mean(difference_matrix)
## [1] -5.191025e-19
#because the difference between the league's matrix and SLN's matrix is negative that means the SLN' matrix was greater. Therefore, the 2016 Cardinals were more likely to end the half-inning after 3 PAs compared to league
count_runners_out = function(s){
s %>% str_split("") %>% pluck(1) %>% as.numeric() %>% sum(na.rm = TRUE)
}
runners_out = sapply(row.names(T_matrix_2016),
count_runners_out)[-25]
R = outer(runners_out + 1, runners_out, FUN = "-")
names(R) = names(T_matrix_2016)[-25]
R = cbind(R, rep(0,24))
set.seed(430)
simulate_half_inning = function(P, R, start = 1){
s = start
path = NULL
runs = 0
while(s < 25){
s.new = sample(1:25, size = 1, prob = P[s, ])
path = c(path, s.new)
runs = runs + R[s, s.new]
s = s.new
}
runs
}
B = 1e5
system.time({
RUNS = replicate(B, simulate_half_inning(P_matrix_2016, R))
})
## user system elapsed
## 7.91 0.11 8.03
RUNS.j = function(j){
mean(replicate(B, simulate_half_inning(P_matrix_2016, R, j)))
}
#doMC is not compatible with my computer (Windows) so hopefully this code replaces what the notes achieves. If it does not, I also have included the function that is in the notes to get the RE24 matrix
cl <- makeCluster(detectCores() - 2)
registerDoParallel(cl)
RNGkind(kind = "L'Ecuyer-CMRG")
system.time({
RE_bat <- foreach(j = 1:24, .combine = 'c') %dopar% RUNS.j(j) %>%
unlist() %>%
matrix(nrow = 8, ncol = 3, byrow = TRUE,
dimnames = list(c("000","001","010","011",
"100","101","110","111"),
c("0 outs", "1 out", "2 outs")))
})
## user system elapsed
## 0.06 0.00 33.66
stopCluster(cl)
round(RE_bat, 2)
## 0 outs 1 out 2 outs
## 000 0.50 0.25 0.09
## 001 1.34 0.97 0.39
## 010 1.14 0.67 0.32
## 011 2.01 1.48 0.58
## 100 0.83 0.49 0.20
## 101 1.76 1.23 0.47
## 110 1.51 0.89 0.38
## 111 2.52 1.52 0.66
#library(doMC)
#library(parallel)
#registerDoMC(cores=detectCores()-2)
#RNGkind(kind = "L'Ecuyer-CMRG")
#system.time({
# RE_bat = foreach(j = 1:24) %dopar% RUNS.j(j) %>%
# unlist() %>%
# matrix(nrow = 8, ncol = 3, byrow = TRUE,
# dimnames =list(c("000","001","010","011",
# "100","101","110","111"),
# c("0 outs", "1 out", "2 outs")))
#})
#round(RE_bat, 2)
Question 3 Problem 5 in Section 5.11 of Analyzing Baseball Data with R. Suppose one is interested in studying how runners move with a single.
singles <- dat2016_updated%>%
filter(EVENT_CD == 20)
singles